package com.ruoyi.zhgd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.zhgd.domain.*;
import com.ruoyi.zhgd.domain.bo.ZjNWarningUserMessageBo;
import com.ruoyi.zhgd.domain.vo.*;
import com.ruoyi.zhgd.mapper.*;
import com.ruoyi.zhgd.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.zhgd.domain.bo.NAsphaltDataBo;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 沥青拌合站数据Service业务层处理
 *
 * @author zyb
 * @date 2023-09-06
 */
@RequiredArgsConstructor
@Service
@DS("sjcj")
public class NAsphaltDataServiceImpl implements INAsphaltDataService {

    private final NAsphaltDataMapper baseMapper;

    private final INAsphaltMatchService inAsphaltMatchService;

    private final INAsphaltMatchThresholdService inAsphaltMatchThresholdService;

    private final INAsphaltMatchTypeService inAsphaltMatchTypeService;

    private final INAsphaltMatchHotService inAsphaltMatchHotService;

    private final INSysStationService inSysStationService;

    private final INAsphaltDataSieveService inAsphaltDataSieveService;

    private final NAsphaltMatchMapper nAsphaltMatchMapper;

    private final SysDeptMapper sysDeptMapper;

    private final ZjNWarningUserMessageMapper zjNWarningUserMessageMapper;

    private final ZjNWarningUsingMapper zjNWarningUsingMapper;

    private final IZjNWarningUsingService iZjNWarningUsingService;

    private final ZjNWarningSwlqMapper zjNWarningSwlqMapper;

    private final NAsphaltDataWeightMapper nAsphaltDataWeightMapper;

    private final ZjNAsphaltMatchMapper zjNAsphaltMatchMapper;

    private final INAsphaltDataWeightService inAsphaltDataWeightService;

    private final NWarningManagementMapper nWarningManagementMapper;

    private final ZjNWarningLqMapper zjNWarningLqMapper;

    /**
     * 查询沥青拌合站数据
     */
    @Override
    public NAsphaltDataVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    @Override
    public NAsphaltDataVo getById(String id) {
        return baseMapper.getById(id);
    }

    /**
     * 查询沥青拌合站数据列表
     */
    @Override
    public TableDataInfo<NAsphaltDataVo> queryPageList(NAsphaltDataBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<NAsphaltData> lqw = buildQueryWrapper(bo);
        Page<NAsphaltDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询沥青拌合站数据列表
     */
    @Override
    public List<NAsphaltDataVo> queryList(NAsphaltDataBo bo) {
        LambdaQueryWrapper<NAsphaltData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<NAsphaltData> buildQueryWrapper(NAsphaltDataBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<NAsphaltData> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getBaseCode()), NAsphaltData::getBaseCode, bo.getBaseCode());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptId()), NAsphaltData::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptPkid()), NAsphaltData::getDeptPkid, bo.getDeptPkid());
        lqw.eq(StringUtils.isNotBlank(bo.getProjectId()), NAsphaltData::getProjectId, bo.getProjectId());
        lqw.eq(StringUtils.isNotBlank(bo.getStationId()), NAsphaltData::getStationId, bo.getStationId());
        lqw.eq(StringUtils.isNotBlank(bo.getMatchType()), NAsphaltData::getMatchType, bo.getMatchType());
        lqw.like(StringUtils.isNotBlank(bo.getMatchName()), NAsphaltData::getMatchName, bo.getMatchName());
        lqw.eq(StringUtils.isNotBlank(bo.getMatchCode()), NAsphaltData::getMatchCode, bo.getMatchCode());
        lqw.eq(bo.getDischargeTime() != null, NAsphaltData::getDischargeTime, bo.getDischargeTime());
        lqw.eq(bo.getDischargeTemperature() != null, NAsphaltData::getDischargeTemperature, bo.getDischargeTemperature());
        lqw.eq(bo.getSluiceTemperature() != null, NAsphaltData::getSluiceTemperature, bo.getSluiceTemperature());
        lqw.eq(bo.getBatchWeight() != null, NAsphaltData::getBatchWeight, bo.getBatchWeight());
        lqw.eq(bo.getMixingDuration() != null, NAsphaltData::getMixingDuration, bo.getMixingDuration());
        lqw.eq(bo.getAsphaltTemperature() != null, NAsphaltData::getAsphaltTemperature, bo.getAsphaltTemperature());
        lqw.eq(bo.getAsphaltAggregateRatio() != null, NAsphaltData::getAsphaltAggregateRatio, bo.getAsphaltAggregateRatio());
        lqw.eq(bo.getInsertTime() != null, NAsphaltData::getInsertTime, bo.getInsertTime());
        lqw.eq(StringUtils.isNotBlank(bo.getProductionType()), NAsphaltData::getProductionType, bo.getProductionType());
        lqw.eq(StringUtils.isNotBlank(bo.getProjectCode()), NAsphaltData::getProjectCode, bo.getProjectCode());
        lqw.eq(StringUtils.isNotBlank(bo.getStationCode()), NAsphaltData::getStationCode, bo.getStationCode());
        lqw.eq(StringUtils.isNotBlank(bo.getOriginalId()), NAsphaltData::getOriginalId, bo.getOriginalId());
        return lqw;
    }

    /**
     * 新增沥青拌合站数据
     */
    @Override
    public Boolean insertByBo(NAsphaltDataBo bo) {
        NAsphaltData add = BeanUtil.toBean(bo, NAsphaltData.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改沥青拌合站数据
     */
    @Override
    public Boolean updateByBo(NAsphaltDataBo bo) {
        NAsphaltData update = BeanUtil.toBean(bo, NAsphaltData.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(NAsphaltData entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除沥青拌合站数据
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 获取最新数据
     *
     * @param bo
     * @return
     */
    @Override
    public NAsphaltDataVo getLatestData(NAsphaltDataBo bo) {
        NAsphaltData data = new NAsphaltData();
        // 时间赋值,条件查询
        if (ObjectUtils.isNotEmpty(bo.getDay())) {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd");
            try {
                bo.setDischargeTime(sdf.parse(bo.getDay()));
                LambdaQueryWrapper<NAsphaltData> lqw = buildQueryWrapper(bo);
                data = baseMapper.selectOne(lqw);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            data = baseMapper.getLatestData(bo);
        }
        return BeanUtil.toBean(data, NAsphaltDataVo.class);
    }

    /**
     * 获取全天生产数据
     *
     * @param bo
     * @return
     */
    @Override
    public NAsphaltDataResVo getDayChartData(NAsphaltDataBo bo) {
        if (ObjectUtils.isEmpty(bo.getMatchCode()) || ObjectUtils.isEmpty(bo.getDay())) {
            return null;
        }
        NAsphaltDataResVo dataVo = new NAsphaltDataResVo();
        // 获取配方编号
        NAsphaltMatch asphaltMatchEntity = inAsphaltMatchService.getByCode(bo.getMatchCode());
        if (ObjectUtils.isNotEmpty(asphaltMatchEntity)) {
            // 获取上下限
            NAsphaltMatchThreshold matchThresholdEntity = inAsphaltMatchThresholdService.getByMatchName(asphaltMatchEntity.getMatchName());
            dataVo.setMatchThreshold(matchThresholdEntity);
            // 获取级配类型
            NAsphaltMatchType matchTypeEntity = inAsphaltMatchTypeService.getByType(asphaltMatchEntity.getMatchType());
            dataVo.setAsphaltMatchType(matchTypeEntity);
            // 获取热料配置信息
            Map<String, Double> targetMap = inAsphaltMatchHotService.getTargetMap(asphaltMatchEntity.getId());
            dataVo.setTargetMap(targetMap);
            bo.setStationCode(asphaltMatchEntity.getStationCode());
        }
        // 获取拌合楼信息
        NSysStation station = null;
        if (ObjectUtils.isNotEmpty(bo.getStationCode())) {
            station = inSysStationService.getStationByCode(bo.getStationCode());
        }
        dataVo.setStation(station);
        // 获取筛分数据
        List<NAsphaltDataSieveVo> sieveDataList = inAsphaltDataSieveService.listForDay(bo.getStationCode(), bo.getMatchCode(), bo.getDay());
        dataVo.setSieveDataList(sieveDataList);
        return dataVo;
    }

    /**
     * 获取配方编号列表
     *
     * @return
     */
    @Override
    public R<List<Map<String, Object>>> getInitMatchCode() {
        List<NAsphaltMatch> list = nAsphaltMatchMapper.selectList(new QueryWrapper<NAsphaltMatch>().orderByAsc("id").groupBy("match_code"));
        List<Map<String, Object>> data = new ArrayList<>();
        list.forEach(val -> {
            Map<String, Object> map = new HashMap<>();
            map.put("value", val.getMatchCode());
            map.put("label", val.getMatchCode());
            data.add(map);
        });
        return R.ok(data);
    }

    /**
     * 油石比检测
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<NAsphaltProduceDataVo> produceAsphaltAggregate(NAsphaltDataBo bo, PageQuery pageQuery) {
        return TableDataInfo.build(baseMapper.produceAsphaltAggregate(bo, pageQuery.build()));
    }

    /**
     * 数据采集校验
     * @param id
     */
    @Override
    @Transactional
    public void isQualified(String id) {
        NAsphaltDataWeightVo vo = baseMapper.getDataWeightById(id);
        if (ObjectUtils.isEmpty(vo)) {
            // 不预警
            System.err.println("没有查询到对应的沥青生产信息,不作预警.");
            return;
        } else {
            String deptId = vo.getDeptId();
            // 判断是否存在部门信息,没有则为合格
            if (ObjectUtils.isEmpty(deptId)) {
                // 不预警
                System.err.println("没有查询到对应的部门信息,不作预警.");
                return;
            } else {
                // 获取差值百分比
                NAsphaltDataWeightVo cz = new NAsphaltDataWeightVo();
                List<NAsphaltDataWeightVo> list = new ArrayList<>();
                list.add(vo);
                List<NAsphaltDataWeightVo> data = inAsphaltDataWeightService.handleList(list, true, true);
                for (NAsphaltDataWeightVo datum : data) {
                    if (ObjectUtils.isNotEmpty(datum.getDesc()) && "差值百分比".equals(datum.getDesc())) {
                        cz = datum;
                    }
                }

                // 根据部门获取配比信息,有则预警,没有则不作预警判断
                LambdaQueryWrapper<ZjNAsphaltMatch> lqw =  Wrappers.lambdaQuery();
                lqw.eq(ZjNAsphaltMatch::getStationCode, deptId);
                ZjNAsphaltMatch match = zjNAsphaltMatchMapper.selectOne(lqw);
                if (ObjectUtils.isEmpty(match) || ObjectUtils.isEmpty(cz)) {
                    // 不预警
                    System.err.println("没有查询到对应的配比信息/差值信息,不作预警.");
                    return;
                } else {
                    // 差值对比,预警保存,短信发送
                    compare(match, cz);
                }
            }
        }

    }

    /**
     * 手动校验
     *
     * @param bo
     */
    @Override
    public void handCheck(NAsphaltDataBo bo) {
        if (org.apache.commons.lang3.ObjectUtils.isEmpty(bo.getIds())) {
            throw new ServiceException("ID列表不能为空");
        }
        List<String> ids = bo.getIds();
        // 去重
        ids = new ArrayList<>(new HashSet<>(ids));
        for (String id : ids) {
            // 调用判断方法
            isQualified(id);
        }
    }

    List<ZjNWarningLq> warnList = new ArrayList<>();

    /**
     * 沥青生产数据差值和配比对比
     * @param match
     * @param vo
     */
    @Transactional
    public void compare(ZjNAsphaltMatch match, NAsphaltDataWeightVo vo) {
        // 初始化预警消息
        warnList = new ArrayList<>();
        // 骨料1
        if (ObjectUtils.isNotEmpty(match.getGravel1Min()) && ObjectUtils.isNotEmpty(match.getGravel1Max()) && ObjectUtils.isNotEmpty(vo.getGravel1Act())) {
            BigDecimal gravelMin = match.getGravel1Min();
            BigDecimal gravelMax = match.getGravel1Max();
            BigDecimal gravelAct = vo.getGravel1Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料1 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    // 取绝对值
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                    // 对比初中高
                }
                else { // 正的
                    // 取绝对值
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                    // 对比初中高
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料1", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料2
        if (ObjectUtils.isNotEmpty(match.getGravel2Min()) && ObjectUtils.isNotEmpty(match.getGravel2Max()) && ObjectUtils.isNotEmpty(vo.getGravel2Act())) {
            BigDecimal gravelMin = match.getGravel2Min();
            BigDecimal gravelMax = match.getGravel2Max();
            BigDecimal gravelAct = vo.getGravel2Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料2 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料2", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料3
        if (ObjectUtils.isNotEmpty(match.getGravel3Min()) && ObjectUtils.isNotEmpty(match.getGravel3Max()) && ObjectUtils.isNotEmpty(vo.getGravel3Act())) {
            BigDecimal gravelMin = match.getGravel3Min();
            BigDecimal gravelMax = match.getGravel3Max();
            BigDecimal gravelAct = vo.getGravel3Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料3 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料3", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料4
        if (ObjectUtils.isNotEmpty(match.getGravel4Min()) && ObjectUtils.isNotEmpty(match.getGravel4Max()) && ObjectUtils.isNotEmpty(vo.getGravel4Act())) {
            BigDecimal gravelMin = match.getGravel4Min();
            BigDecimal gravelMax = match.getGravel4Max();
            BigDecimal gravelAct = vo.getGravel4Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料4 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料4", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料5
        if (ObjectUtils.isNotEmpty(match.getGravel5Min()) && ObjectUtils.isNotEmpty(match.getGravel5Max()) && ObjectUtils.isNotEmpty(vo.getGravel5Act())) {
            BigDecimal gravelMin = match.getGravel5Min();
            BigDecimal gravelMax = match.getGravel5Max();
            BigDecimal gravelAct = vo.getGravel5Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料5 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料5", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料6
        if (ObjectUtils.isNotEmpty(match.getGravel6Min()) && ObjectUtils.isNotEmpty(match.getGravel6Max()) && ObjectUtils.isNotEmpty(vo.getGravel6Act())) {
            BigDecimal gravelMin = match.getGravel6Min();
            BigDecimal gravelMax = match.getGravel6Max();
            BigDecimal gravelAct = vo.getGravel6Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料6 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "骨料6", abs.toString());
                warnList.add(entity);
            }
        }
        // 粉料1
        if (ObjectUtils.isNotEmpty(match.getPowder1Min()) && ObjectUtils.isNotEmpty(match.getPowder1Max()) && ObjectUtils.isNotEmpty(vo.getPowder1Act())) {
            BigDecimal gravelMin = match.getPowder1Min();
            BigDecimal gravelMax = match.getPowder1Max();
            BigDecimal gravelAct = vo.getPowder1Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 粉料1 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "粉料1", abs.toString());
                warnList.add(entity);
            }
        }
        // 粉料2
        if (ObjectUtils.isNotEmpty(match.getPowder2Min()) && ObjectUtils.isNotEmpty(match.getPowder2Max()) && ObjectUtils.isNotEmpty(vo.getPowder2Act())) {
            BigDecimal gravelMin = match.getPowder2Min();
            BigDecimal gravelMax = match.getPowder2Max();
            BigDecimal gravelAct = vo.getPowder2Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 粉料2 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "粉料2", abs.toString());
                warnList.add(entity);
            }
        }
        // 粉料3
        if (ObjectUtils.isNotEmpty(match.getPowder3Min()) && ObjectUtils.isNotEmpty(match.getPowder3Max()) && ObjectUtils.isNotEmpty(vo.getPowder3Act())) {
            BigDecimal gravelMin = match.getPowder3Min();
            BigDecimal gravelMax = match.getPowder3Max();
            BigDecimal gravelAct = vo.getPowder3Act();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 粉料3 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "粉料3", abs.toString());
                warnList.add(entity);
            }
        }
        // 再生料
        if (ObjectUtils.isNotEmpty(match.getRecycledMaterialMin()) && ObjectUtils.isNotEmpty(match.getRecycledMaterialMax()) && ObjectUtils.isNotEmpty(vo.getRecycledMaterialAct())) {
            BigDecimal gravelMin = match.getRecycledMaterialMin();
            BigDecimal gravelMax = match.getRecycledMaterialMax();
            BigDecimal gravelAct = vo.getRecycledMaterialAct();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 再生料 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "再生料", abs.toString());
                warnList.add(entity);
            }
        }
        // 沥青
        if (ObjectUtils.isNotEmpty(match.getAsphaltMin()) && ObjectUtils.isNotEmpty(match.getAsphaltMax()) && ObjectUtils.isNotEmpty(vo.getAsphaltAct())) {
            BigDecimal gravelMin = match.getAsphaltMin();
            BigDecimal gravelMax = match.getAsphaltMax();
            BigDecimal gravelAct = vo.getAsphaltAct();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 沥青 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "沥青", abs.toString());
                warnList.add(entity);
            }
        }
        // 温度
        if (ObjectUtils.isNotEmpty(match.getAsphaltTemperatureMin()) && ObjectUtils.isNotEmpty(match.getAsphaltTemperatureMax()) && ObjectUtils.isNotEmpty(vo.getAsphaltTemperature())) {
            BigDecimal gravelMin = match.getAsphaltTemperatureMin();
            BigDecimal gravelMax = match.getAsphaltTemperatureMax();
            BigDecimal gravelAct = vo.getAsphaltTemperature();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 温度 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "温度", abs.toString());
                warnList.add(entity);
            }
        }
        // 油石比
        if (ObjectUtils.isNotEmpty(match.getAsphaltAggregateRatioMin()) && ObjectUtils.isNotEmpty(match.getAsphaltAggregateRatioMax()) && ObjectUtils.isNotEmpty(vo.getAsphaltAggregateRatio())) {
            BigDecimal gravelMin = match.getAsphaltAggregateRatioMin();
            BigDecimal gravelMax = match.getAsphaltAggregateRatioMax();
            BigDecimal gravelAct = vo.getAsphaltAggregateRatio();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 油石比 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningLq entity = saveWarnInfo(vo, level, "油石比", abs.toString());
                warnList.add(entity);
            }
        }
        // 发送短信通知
        send(vo.getDeptId(), vo, warnList, 1);
    }
    BigDecimal extra = BigDecimal.ZERO;
    /**
     * 获取初中高预警等级
     * @param data
     * @param deptId
     * @return
     */
    public int getLevel(BigDecimal data, String deptId) {
        int level = 0;
        // 获取沥青对应部门的初中高预警等级范围
        LambdaQueryWrapper<NWarningManagement> lqw = new LambdaQueryWrapper<>();
        lqw.eq(NWarningManagement::getTypeId, "0");
        lqw.eq(NWarningManagement::getDeptId, deptId);
        NWarningManagement entity = nWarningManagementMapper.selectOne(lqw);
        if (ObjectUtils.isEmpty(entity)) {
            return 0;
        }
//        extra = BigDecimal.ZERO;
        // 初级下限
        if (ObjectUtils.isNotEmpty(entity.getDownLowWarning()) && data.compareTo(entity.getDownLowWarning()) < 0) {
            level = 0;
//            extra = data.subtract(entity.getDownLowWarning());
        }
        // 初级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpLowWarning()) && data.compareTo(entity.getUpLowWarning()) <= 0) {
            level = 1;
//            extra = data.subtract(entity.getUpLowWarning());
        }
        // 中级下限
        else if (ObjectUtils.isNotEmpty(entity.getDownMiddleWarning()) && data.compareTo(entity.getDownMiddleWarning()) < 0) {
            level = 1;
//            extra = data.subtract(entity.getDownMiddleWarning());
        }
        // 中级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpMiddleWarning()) && data.compareTo(entity.getUpMiddleWarning()) <= 0) {
            level = 2;
//            extra = data.subtract(entity.getUpMiddleWarning());
        }
        // 高级下限
        else if (ObjectUtils.isNotEmpty(entity.getDownAdvancedWarning()) && data.compareTo(entity.getDownAdvancedWarning()) < 0) {
            level = 2;
//            extra = data.subtract(entity.getDownAdvancedWarning());
        }
        // 高级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpAdvancedWarning()) && data.compareTo(entity.getUpAdvancedWarning()) <= 0) {
            level = 3;
//            extra = data.subtract(entity.getUpAdvancedWarning());
        }
        else {
            level = 4;
        }
        return level;
    }

    /**
     * 保存预警信息
     * @param vo
     * @param level
     * @param warnItem
     * @param outRange
     */
    @Transactional
    public ZjNWarningLq saveWarnInfo(NAsphaltDataWeightVo vo, int level, String warnItem, String outRange) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = "";
        if (ObjectUtils.isNotEmpty(vo.getDischargeTime())) {
            date = sdf.format(vo.getDischargeTime());
        }
        String gd = "";
        if (level == 1) {
            gd = "初级";
        } else if (level == 2) {
            gd = "中级";
        } else if (level == 3) {
            gd = "高级";
        }
        ZjNWarningLq entity = new ZjNWarningLq();
        entity.setGrade(String.valueOf(level));
        entity.setInsterTime(new Date());
        entity.setRemark(warnItem+"产生了" + gd + "预警");
        entity.setBusinessId(vo.getId());
        entity.setDisposalStatus(1);
        entity.setStationCode(vo.getDeptId());
        entity.setBuzTime(date);
        entity.setMatchName(vo.getMatchName());
        entity.setWarnItem(warnItem);
        entity.setOutRange(outRange);
        entity.setDelFlag("0");

        switch (warnItem) {
            case "骨料1":
                entity.setCz(vo.getGravel1Act().toString());
                break;
            case "骨料2":
                entity.setCz(vo.getGravel2Act().toString());
                break;
            case "骨料3":
                entity.setCz(vo.getGravel3Act().toString());
                break;
            case "骨料4":
                entity.setCz(vo.getGravel4Act().toString());
                break;
            case "骨料5":
                entity.setCz(vo.getGravel5Act().toString());
                break;
            case "骨料6":
                entity.setCz(vo.getGravel6Act().toString());
                break;
            case "粉料1":
                entity.setCz(vo.getPowder1Act().toString());
                break;
            case "粉料2":
                entity.setCz(vo.getPowder2Act().toString());
                break;
            case "粉料3":
                entity.setCz(vo.getPowder3Act().toString());
                break;
            case "沥青":
                entity.setCz(vo.getAsphaltAct().toString());
                break;
            case "再生料":
                entity.setCz(vo.getRecycledMaterialAct().toString());
                break;
            case "温度":
                entity.setCz(vo.getAsphaltTemperature().toString());
                break;
            case "油石比":
                entity.setCz(vo.getAsphaltAggregateRatio().toString());
                break;
        }

        zjNWarningLqMapper.insert(entity);
        return entity;
    }

    /**
     * 短信通知
     * @param deptId
     * @param vo
     * @param warnList
     * @param isSend
     */
    @Transactional
    private void send(String deptId, NAsphaltDataWeightVo vo, List<ZjNWarningLq> warnList, int isSend) {
        if (isSend != 1) {
            System.err.println("不发送沥青预警信息...");
            return;
        }
        String message = "";
        String deptName = ObjectUtils.isNotEmpty(vo.getDeptName()) ? vo.getDeptName() + "-" : "[标段]-";
        String stationName = "沥青拌合站-";
        message = message + deptName + stationName;

        String matchName = "";
        String buzTime = "";
        String forMsg = "";
        // 样例：
        // 短信内容编辑
        for (ZjNWarningLq entity : warnList) {
            // 配比名称
            matchName = "配方名称:" + (ObjectUtils.isNotEmpty(entity.getMatchName()) ? entity.getMatchName(): "");
            // 业务数据时间
            buzTime = entity.getBuzTime();
            // 预警项目
            String warnItem = entity.getWarnItem();
            // 误差
            String cz = entity.getCz();
            // 超出比例
            String outRange = entity.getOutRange();
            // 预警级别
            String grade = entity.getGrade();
            String level = "";
            if (StringUtils.isNotEmpty(grade)) {
                if ("1".equals(grade)) {
                    level = "初级预警";
                }
                else if ("2".equals(grade)) {
                    level = "中级预警";
                }
                else if ("3".equals(grade)) {
                    level = "高级预警";
                }
                else {
                    level = "预警";
                }
            } else {
                level = "预警";
            }
            // 编辑消息
            forMsg = forMsg + warnItem + "误差" + cz + "%" + "超出上下限" + outRange + "%产生了" + level + ";";
        }
        message = message + matchName;
        message = message + "("+buzTime+")的";
        message = message + forMsg;
        System.err.println("预警消息:" + message);

        // 根据deptId获取祖级列表
        SysDept dept = sysDeptMapper.getById(Long.valueOf(deptId));
        String ancestors = ObjectUtils.isNotEmpty(dept) ? dept.getAncestors() : null;
        String[] ids = ObjectUtils.isNotEmpty(ancestors) ? ancestors.split(",") : new String[]{} ;
        // 根据部门id获取预警标识
        ZjNWarningUsing entity = zjNWarningUsingMapper.getByDeptId(deptId, ids);
        Long open = ObjectUtils.isNotEmpty(entity) ? entity.getUsingMsgLq() : 0;
        if (open != 1) {
            System.err.println("沥青短信通知已关闭...");
            return;
        }
        // 发送人获取:
        ZjNWarningUserMessageBo bo = new ZjNWarningUserMessageBo();
        bo.setId(deptId);
        QueryWrapper<ZjNWarningUserMessage> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("a.del_flag", "0");
        wrapper1.eq("u.del_flag", "0");
        wrapper1.like("a.warn_val_lq", "1");
        List<ZjNWarningUserMessageVo> list = zjNWarningUserMessageMapper.getZlyjList(wrapper1, bo);
        List<String> phonenumber = list.stream().map(ZjNWarningUserMessageVo::getPhonenumber).collect(Collectors.toList());
        // 发送短信
        try {
            // 推送失败 返1 成功 返0
            int send = iZjNWarningUsingService.send(phonenumber, message);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("短信发送失败");
        }

    }


}
